package com.youkeyi.ddy.cloud.application.system.login.controller;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.alibaba.fastjson.JSON;
import com.youkeyi.ddy.cloud.application.system.login.dto.LoginDto;
import com.youkeyi.ddy.cloud.application.system.login.dto.RespWxPhone;
import com.youkeyi.ddy.cloud.application.system.login.service.LoginService;
import com.youkeyi.ddy.cloud.common.annotation.PassToken;
import com.youkeyi.ddy.cloud.common.api.application.system.login.SystemAppletLoginFeignService;
import com.youkeyi.ddy.cloud.common.api.application.system.login.dto.AppletLoginAuthCloudDto;
import com.youkeyi.ddy.cloud.common.api.application.system.login.param.AppletLoginAuthCloudParam;
import com.youkeyi.ddy.cloud.common.api.basic.pub.user.PublicUserCloudService;
import com.youkeyi.ddy.cloud.common.api.basic.pub.user.param.PublicUserUpdateCloudParam;
import com.youkeyi.ddy.cloud.common.constant.YoukeyiDdyApplicationSystemConstant;
import com.youkeyi.ddy.cloud.common.context.YoukeyiSystemContext;
import com.youkeyi.ddy.cloud.common.enums.ResponseCodeEnum;
import com.youkeyi.ddy.cloud.common.response.ResponseContent;
import com.youkeyi.ddy.cloud.common.response.ResponseObjectContent;
import com.youkeyi.ddy.cloud.common.utils.RedisUtils;
import com.youkeyi.ddy.cloud.common.utils.SimpleUUidUtils;
import com.youkeyi.ddy.cloud.common.utils.WxAESUtil;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * SystemAppletLoginController
 *
 * @Author liuxiawang
 * @Date 2024/4/23 3:52 PM
 * @Location shenzhen.china
 */
@Slf4j
@Service
public class SystemAppletLoginController implements SystemAppletLoginFeignService {

    @Autowired
    private WxMaService wxMaService;
    @Autowired
    private LoginService loginService;
    @Autowired
    private PublicUserCloudService publicUserCloudService;

    @Override
    @PassToken
    public AppletLoginAuthCloudDto getWxInfo(String code) {
        AppletLoginAuthCloudDto dto = new AppletLoginAuthCloudDto();
        if (StringUtils.isNotBlank(code)) {
            WxMaJscode2SessionResult wx;
            try {
                wx = wxMaService.jsCode2SessionInfo(code);
                log.info("请求微信授权完成=>{}", wx);
                dto.setOpenid(wx.getOpenid());
                dto.setSessionKey(wx.getSessionKey());
                dto.setUnionid(wx.getUnionid());
                dto.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
                return dto;
            } catch (WxErrorException e) {
                e.printStackTrace();
                dto.setErrorMessage(e.getMessage());
                return dto;
            }
        }else {
            dto.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
        }
        return dto;
    }


    @Override
    @PassToken
    public ResponseObjectContent getToken(AppletLoginAuthCloudParam param) {
        ResponseObjectContent<LoginDto> rc = new ResponseObjectContent<>();
        if (StringUtils.isBlank(param.getSessionKey()) || StringUtils.isBlank(param.getIv())
                || StringUtils.isBlank(param.getEncryptedData())) {
            rc.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return rc;
        }

        // 解析得到手机号
        String rawPhoneInfo;
        try {
            rawPhoneInfo = WxAESUtil.wxDecrypt(param.getEncryptedData(), param.getSessionKey(), param.getIv());
        } catch (Exception e) {
            log.error("", e);
            rc.setErrorMessage("解析手机号失败");
            return rc;
        }
        log.info("EncryptedData: {}", rawPhoneInfo);
        RespWxPhone respWxPhone = JSON.parseObject(rawPhoneInfo, RespWxPhone.class);
        String phone = respWxPhone.getPhoneNumber();
        // redis key
        String token = SimpleUUidUtils.getUuid();

        LoginDto loginDto = loginService.login(phone, "", token, "minApp");
        rc.setData(loginDto);
        rc.setSuccess(loginDto.isSuccess());
        rc.setMessage(loginDto.getMessage());

        // 修改user表的小程序的open id跟微信union id
        if (StringUtils.isNotBlank(loginDto.getUserPrimaryKey())
                && StringUtils.isNotBlank(param.getOpenid()) && StringUtils.isNotBlank(param.getUnionid())) {
            PublicUserUpdateCloudParam userUpdateCloudParam = new PublicUserUpdateCloudParam();
            userUpdateCloudParam.setUserPrimaryKey(loginDto.getUserPrimaryKey());
            userUpdateCloudParam.setOpenId(param.getOpenid());
            userUpdateCloudParam.setIsRoot(loginDto.getIsRoot());
            userUpdateCloudParam.setUnionId(param.getUnionid());
            userUpdateCloudParam.setUpdateUserKey(YoukeyiSystemContext.getUserPrimaryKey());
            userUpdateCloudParam.setUpdateUserName(YoukeyiSystemContext.getUserName());
            publicUserCloudService.update(userUpdateCloudParam);
        }
        return rc;
    }

    @Override
    public ResponseContent logout(HttpServletRequest request, HttpServletResponse response) {
        ResponseContent rc = new ResponseContent();
        String token = request.getHeader(YoukeyiDdyApplicationSystemConstant.AUTH_REDIS_TOKEN_KEY);
        try {
            RedisUtils.delKeyFromJedis(YoukeyiDdyApplicationSystemConstant.AUTH_REDIS_DB_INDEX, token);
            rc.setSuccessMessage("登出成功");
        } catch (Exception e) {
            e.printStackTrace();
            rc.setErrorMessage("登出失败");
        }
        return rc;
    }
}
